package org.coldlife.sim.grav;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.vecmath.Vector3d;

public class World 
{
	public final static double G = 6.67300e-11;
	
	private List<MassParitcle> particles;

	private static double MIN_GRAV_DIST = 5;
	private static double MAX_TIME_STEP = .01;
	private static double MASS = 100000;
	
	public World(int num) 
	{
		particles = new ArrayList<MassParitcle>(num);
		ParticleFactory factory = new RandomPositionFactory(MASS);
		while(particles.size() < num)
		{
			particles.add(factory.create());
		}
	}
	
	public void update(double totalTime)
	{
		double t = totalTime;
		t = Math.min(totalTime, MAX_TIME_STEP);
		
		// calc the force of all particle 
		for (MassParitcle particleA : particles) 
		{
			for (MassParitcle particleB : particles)
			{
				// Don't count yourself.
				if(particleA==particleB)
					continue;
				
				double r = particleA.getDistance(particleB);

				// Gravity is too strong beyond this point. So ignore it for now.
				if(r < MIN_GRAV_DIST )
					continue;
				
				double ma = particleA.getMass();
				double mb = particleB.getMass();
				
				// Get the direction gravity is pulling.
				Vector3d gravVec = particleB.getDisplacement(particleA);
				gravVec.normalize();
				
				// Calc the strength of gravity
				double gravMag = G * ma * mb / (r * r);
				
				// Puts strength and direction together.
				gravVec.scale(gravMag);
				
				// Add it to the netForce acting on the this particle.
				particleA.applyForce(gravVec);
			}
		}

		for (MassParitcle particle : particles) 
		{
			particle.updatePosition(t);
		}
		
		for (MassParitcle p : particles) {
			p.resetForce();
		}
		
	}

	public List<? extends Particle> getParticles() {
		return Collections.unmodifiableList(particles);
	}

	public void setParticles(List<MassParitcle> particles) {
		this.particles = particles;
	}
}
